<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,IE=9,chrome=1"><meta name="generator" content="MATLAB 2021b"><title>Exchange Data with ROS Publishers and Subscribers</title><style type="text/css">.rtcContent { padding: 30px; } .S0 { margin: 3px 10px 5px 4px; padding: 0px; line-height: 28.8px; min-height: 0px; white-space: pre-wrap; color: rgb(213, 80, 0); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 24px; font-weight: 400; text-align: left;  }
.S1 { margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(0, 0, 0); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left;  }
.S2 { margin: 10px 0px 20px; padding-left: 0px; font-family: Helvetica, Arial, sans-serif; font-size: 14px;  }
.S3 { margin-left: 56px; line-height: 21px; min-height: 0px; text-align: left; white-space: pre-wrap;  }
.S4 { margin: 20px 10px 5px 4px; padding: 0px; line-height: 20px; min-height: 0px; white-space: pre-wrap; color: rgb(60, 60, 60); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 20px; font-weight: 700; text-align: left;  }
.CodeBlock { background-color: #F7F7F7; margin: 10px 0 10px 0;}
.S5 { border-left: 1px solid rgb(233, 233, 233); border-right: 1px solid rgb(233, 233, 233); border-top: 1px solid rgb(233, 233, 233); border-bottom: 1px solid rgb(233, 233, 233); border-radius: 4px 4px 0px 0px; padding: 6px 45px 4px 13px; line-height: 17.234px; min-height: 18px; white-space: nowrap; color: rgb(0, 0, 0); font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px;  }
.S6 { color: rgb(64, 64, 64); padding: 10px 0px 6px 17px; background: rgb(255, 255, 255) none repeat scroll 0% 0% / auto padding-box border-box; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; overflow-x: hidden; line-height: 17.234px;  }
/* Styling that is common to warnings and errors is in diagnosticOutput.css */.embeddedOutputsErrorElement {    min-height: 18px;    max-height: 550px;}
.embeddedOutputsErrorElement .diagnosticMessage-errorType {    overflow: auto;}
.embeddedOutputsErrorElement.inlineElement {}
.embeddedOutputsErrorElement.rightPaneElement {}
/* Styling that is common to warnings and errors is in diagnosticOutput.css */.embeddedOutputsWarningElement {    min-height: 18px;    max-height: 550px;}
.embeddedOutputsWarningElement .diagnosticMessage-warningType {    overflow: auto;}
.embeddedOutputsWarningElement.inlineElement {}
.embeddedOutputsWarningElement.rightPaneElement {}
/* Copyright 2015-2019 The MathWorks, Inc. *//* In this file, styles are not scoped to rtcContainer since they could be in the Dojo Tooltip */.diagnosticMessage-wrapper {    font-family: Menlo, Monaco, Consolas, "Courier New", monospace;    font-size: 12px;}
.diagnosticMessage-wrapper.diagnosticMessage-warningType {    color: rgb(255,100,0);}
.diagnosticMessage-wrapper.diagnosticMessage-warningType a {    color: rgb(255,100,0);    text-decoration: underline;}
.diagnosticMessage-wrapper.diagnosticMessage-errorType {    color: rgb(230,0,0);}
.diagnosticMessage-wrapper.diagnosticMessage-errorType a {    color: rgb(230,0,0);    text-decoration: underline;}
.diagnosticMessage-wrapper .diagnosticMessage-messagePart,.diagnosticMessage-wrapper .diagnosticMessage-causePart {    white-space: pre-wrap;}
.diagnosticMessage-wrapper .diagnosticMessage-stackPart {    white-space: pre;}
.embeddedOutputsTextElement,.embeddedOutputsVariableStringElement {    white-space: pre;    word-wrap:  initial;    min-height: 18px;    max-height: 550px;}
.embeddedOutputsTextElement .textElement,.embeddedOutputsVariableStringElement .textElement {    overflow: auto;}
.textElement,.rtcDataTipElement .textElement {    padding-top: 3px;}
.embeddedOutputsTextElement.inlineElement,.embeddedOutputsVariableStringElement.inlineElement {}
.inlineElement .textElement {}
.embeddedOutputsTextElement.rightPaneElement,.embeddedOutputsVariableStringElement.rightPaneElement {    min-height: 16px;}
.rightPaneElement .textElement {    padding-top: 2px;    padding-left: 9px;}
.S7 { margin: 10px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(0, 0, 0); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left;  }
.S8 { border-left: 1px solid rgb(233, 233, 233); border-right: 1px solid rgb(233, 233, 233); border-top: 1px solid rgb(233, 233, 233); border-bottom: 1px solid rgb(233, 233, 233); border-radius: 4px; padding: 6px 45px 4px 13px; line-height: 17.234px; min-height: 18px; white-space: nowrap; color: rgb(0, 0, 0); font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px;  }
.S9 { border-left: 1px solid rgb(233, 233, 233); border-right: 1px solid rgb(233, 233, 233); border-top: 1px solid rgb(233, 233, 233); border-bottom: 0px none rgb(0, 0, 0); border-radius: 4px 4px 0px 0px; padding: 6px 45px 0px 13px; line-height: 17.234px; min-height: 18px; white-space: nowrap; color: rgb(0, 0, 0); font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px;  }
.S10 { border-left: 1px solid rgb(233, 233, 233); border-right: 1px solid rgb(233, 233, 233); border-top: 0px none rgb(0, 0, 0); border-bottom: 1px solid rgb(233, 233, 233); border-radius: 0px 0px 4px 4px; padding: 0px 45px 4px 13px; line-height: 17.234px; min-height: 18px; white-space: nowrap; color: rgb(0, 0, 0); font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px;  }
.S11 { border-left: 1px solid rgb(233, 233, 233); border-right: 1px solid rgb(233, 233, 233); border-top: 0px none rgb(0, 0, 0); border-bottom: 1px solid rgb(233, 233, 233); border-radius: 0px; padding: 0px 45px 4px 13px; line-height: 17.234px; min-height: 18px; white-space: nowrap; color: rgb(0, 0, 0); font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px;  }
.S12 { margin: 3px 10px 5px 4px; padding: 0px; line-height: 20px; min-height: 0px; white-space: pre-wrap; color: rgb(60, 60, 60); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 20px; font-weight: 700; text-align: left;  }
.variableValue { width: 100% !important; }
.embeddedOutputsMatrixElement,.eoOutputWrapper .matrixElement {    min-height: 18px;    box-sizing: border-box;}
.embeddedOutputsMatrixElement .matrixElement,.eoOutputWrapper  .matrixElement,.rtcDataTipElement .matrixElement {    position: relative;}
.matrixElement .variableValue,.rtcDataTipElement .matrixElement .variableValue {    white-space: pre;    display: inline-block;    vertical-align: top;    overflow: hidden;}
.embeddedOutputsMatrixElement.inlineElement {}
.embeddedOutputsMatrixElement.inlineElement .topHeaderWrapper {    display: none;}
.embeddedOutputsMatrixElement.inlineElement .veTable .body {    padding-top: 0 !important;    max-height: 100px;}
.inlineElement .matrixElement {    max-height: 300px;}
.embeddedOutputsMatrixElement.rightPaneElement {}
.rightPaneElement .matrixElement,.rtcDataTipElement .matrixElement {    overflow: hidden;    padding-left: 9px;}
.rightPaneElement .matrixElement {    margin-bottom: -1px;}
.embeddedOutputsMatrixElement .matrixElement .valueContainer,.eoOutputWrapper .matrixElement .valueContainer,.rtcDataTipElement .matrixElement .valueContainer {    white-space: nowrap;    margin-bottom: 3px;}
.embeddedOutputsMatrixElement .matrixElement .valueContainer .horizontalEllipsis.hide,.embeddedOutputsMatrixElement .matrixElement .verticalEllipsis.hide,.eoOutputWrapper .matrixElement .valueContainer .horizontalEllipsis.hide,.eoOutputWrapper .matrixElement .verticalEllipsis.hide,.rtcDataTipElement .matrixElement .valueContainer .horizontalEllipsis.hide,.rtcDataTipElement .matrixElement .verticalEllipsis.hide {    display: none;}
.embeddedOutputsVariableMatrixElement .matrixElement .valueContainer.hideEllipses .verticalEllipsis, .embeddedOutputsVariableMatrixElement .matrixElement .valueContainer.hideEllipses .horizontalEllipsis {    display:none;}
.embeddedOutputsMatrixElement .matrixElement .valueContainer .horizontalEllipsis,.eoOutputWrapper .matrixElement .valueContainer .horizontalEllipsis {    margin-bottom: -3px;}
.eoOutputWrapper .embeddedOutputsVariableMatrixElement .matrixElement .valueContainer {    cursor: default !important;}
.embeddedOutputsVariableElement {    white-space: pre-wrap;    word-wrap: break-word;    min-height: 18px;    max-height: 250px;    overflow: auto;}
.variableElement {}
.embeddedOutputsVariableElement.inlineElement {}
.inlineElement .variableElement {}
.embeddedOutputsVariableElement.rightPaneElement {    min-height: 16px;}
.rightPaneElement .variableElement {    padding-top: 2px;    padding-left: 9px;}
.variableNameElement {    margin-bottom: 3px;    display: inline-block;}
/* * Ellipses as base64 for HTML export. */.matrixElement .horizontalEllipsis,.rtcDataTipElement .matrixElement .horizontalEllipsis {    display: inline-block;    margin-top: 3px;    /* base64 encoded version of images-liveeditor/HEllipsis.png */    width: 30px;    height: 12px;    background-repeat: no-repeat;    background-image: url("");}
.matrixElement .verticalEllipsis,.textElement .verticalEllipsis,.rtcDataTipElement .matrixElement .verticalEllipsis,.rtcDataTipElement .textElement .verticalEllipsis {    margin-left: 35px;    /* base64 encoded version of images-liveeditor/VEllipsis.png */    width: 12px;    height: 30px;    background-repeat: no-repeat;    background-image: url("");}
.S13 { border-left: 1px solid rgb(233, 233, 233); border-right: 1px solid rgb(233, 233, 233); border-top: 1px solid rgb(233, 233, 233); border-bottom: 1px solid rgb(233, 233, 233); border-radius: 0px; padding: 6px 45px 4px 13px; line-height: 17.234px; min-height: 18px; white-space: nowrap; color: rgb(0, 0, 0); font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px;  }
.S14 { border-left: 1px solid rgb(233, 233, 233); border-right: 1px solid rgb(233, 233, 233); border-top: 1px solid rgb(233, 233, 233); border-bottom: 1px solid rgb(233, 233, 233); border-radius: 0px 0px 4px 4px; padding: 6px 45px 4px 13px; line-height: 17.234px; min-height: 18px; white-space: nowrap; color: rgb(0, 0, 0); font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px;  }</style></head><body><div class = rtcContent><h1  class = 'S0'><span>Exchange Data with ROS Publishers and Subscribers</span></h1><div  class = 'S1'><span>ROS节点交换数据的主要机制是发送和接收消息</span><span style=' font-style: italic;'>messages</span><span>。消息在一个主题</span><span style=' font-style: italic;'>topic</span><span>上传输，每个主题在ROS网络中都有一个唯一的名称。如果节点想要共享信息，它将使用发布者</span><span style=' font-style: italic;'>publisher</span><span>向主题发送数据。要接收该信息的节点使用同一主题的订阅者</span><span style=' font-style: italic;'>subscriber</span><span>。除了其唯一的名称之外，每个主题还具有一个消息类型</span><span style=' font-style: italic;'>message type</span><span>，该类型决定了能够在该主题下传输的消息的类型。</span></div><div  class = 'S1'><span>此发布者和订阅者通信具有以下特征： </span></div><ul  class = 'S2'><li  class = 'S3'><span>主题用于多对多通信。多个发布者可以向同一主题发送消息，多个订阅者可以接收这些消息。Topics are used for many-to-many communication. Many publishers can send messages to the same topic and many subscribers can receive them.</span></li><li  class = 'S3'><span>发布者和订阅者通过主题分离，可以按任何顺序创建和销毁。即使没有活动订阅服务器，也可以将消息发布到主题。</span></li></ul><div  class = 'S1'><span>主题、发布者和订阅者的概念如图所示：</span></div><div  class = 'S1'><img class = "imageNode" src = "" width = "798" height = "274" alt = "" style = "vertical-align: baseline; width: 798px; height: 274px;"></img></div><div  class = 'S1'><span>这个例子展示了如何在ROS网络中发布和订阅主题。它还展示了如何：</span></div><ul  class = 'S2'><li  class = 'S3'><span>等待收到新消息</span></li><li  class = 'S3'><span>使用回调callbacks在后台处理新消息messages。</span></li></ul><div  class = 'S1'><span>首要条件:</span><span> </span><a href = "docid:ros_ug.mw_cb3fdf75-613d-45b1-90e1-aad102b9a24a"><span>Get Started with ROS</span></a><span>, </span><span> </span><a href = "docid:ros_ug.mw_d625a603-7f37-4925-9470-2de734937434"><span>Connect to a ROS Network</span></a></div><h2  class = 'S4'><span>Subscribe and Wait for Messages</span></h2><div  class = 'S1'><span>使用 </span><a href = "docid:ros_ref.bupf5_j_1"><span style=' font-family: monospace;'>rosinit</span></a><span> 命令在MATLAB®中启动ROS主机。</span></div><div class="CodeBlock"><div class="inlineWrapper outputs"><div  class = 'S5'><span style="white-space: pre"><span >rosinit</span></span></div><div  class = 'S6'><div class="inlineElement eoOutputWrapper embeddedOutputsTextElement" uid="D94C5F52" data-testid="output_0" style="width: 716px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="textElement eoOutputContent" data-width="686" data-height="61" data-hashorizontaloverflow="false" style="max-height: 261px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">Launching ROS Core...
..........Done in 4.1027 seconds.
Initializing ROS master on http://192.168.118.1:11311.
Initializing global node /matlab_global_node_36339 with NodeURI http://LAPTOP-TG3AQJDL:14641/</div></div></div></div></div><div  class = 'S7'><span>使用提供的helper函数exampleHelperROSCreateSampleNetwork创建一个包含多个发布者和订阅者的示例ROS网络。</span></div><div class="CodeBlock"><div class="inlineWrapper"><div  class = 'S8'><span style="white-space: pre"><span >exampleHelperROSCreateSampleNetwork</span></span></div></div></div><div  class = 'S1'><span>使用</span><a href = "docid:ros_ref.bupf5_j_14"><span style=' font-family: monospace;'>rostopic</span></a><span>列表查看哪些主题可用。</span></div><div class="CodeBlock"><div class="inlineWrapper outputs"><div  class = 'S5'><span style="white-space: pre"><span >rostopic </span><span style="color: rgb(170, 4, 249);">list</span></span></div><div  class = 'S6'><div class="inlineElement eoOutputWrapper embeddedOutputsTextElement" uid="ED869719" data-testid="output_1" style="width: 716px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="textElement eoOutputContent" data-width="686" data-height="61" data-hashorizontaloverflow="false" style="max-height: 261px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">/pose  
/rosout
/scan  
/tf    </div></div></div></div></div><div  class = 'S1'><span>使用</span><span style=' font-family: monospace;'>rostopic info</span><span>检查是否有任何节点正在发布到 </span><span style=' font-family: monospace;'>/scan</span><span>主题。下面的命令显示</span><span style=' font-family: monospace;'>node_3</span><span>正在向其发布。</span></div><div class="CodeBlock"><div class="inlineWrapper outputs"><div  class = 'S5'><span style="white-space: pre"><span >rostopic </span><span style="color: rgb(170, 4, 249);">info /scan</span></span></div><div  class = 'S6'><div class="inlineElement eoOutputWrapper embeddedOutputsTextElement" uid="B8891FC4" data-testid="output_2" style="width: 716px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="textElement eoOutputContent" data-width="686" data-height="118" data-hashorizontaloverflow="false" style="max-height: 261px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">Type: sensor_msgs/LaserScan
 
Publishers:
* /node_3 (http://LAPTOP-TG3AQJDL:14661/)
 
Subscribers:
* /node_1 (http://LAPTOP-TG3AQJDL:14649/)
* /node_2 (http://LAPTOP-TG3AQJDL:14655/)</div></div></div></div></div><div  class = 'S1'><span>使用</span><a href = "docid:ros_ref.bupf5_j_9"><span style=' font-family: monospace;'>rossubscriber</span></a><span> 订阅 </span><span style=' font-family: monospace;'>/scan</span><span>主题。如果主题已经存在于ROS网络中（如这里的情况），</span><span style=' font-family: monospace;'>rossubscriber</span><span>会自动检测其消息类型，因此您不需要指定它。</span></div><div class="CodeBlock"><div class="inlineWrapper"><div  class = 'S9'><span style="white-space: pre"><span >laser = rossubscriber(</span><span style="color: rgb(170, 4, 249);">'/scan'</span><span >);</span></span></div></div><div class="inlineWrapper"><div  class = 'S10'><span style="white-space: pre"><span >pause(2)</span></span></div></div></div><div  class = 'S1'><span>使用</span><a href = "docid:ros_ref.buqbyro"><span style=' font-family: monospace;'>receive</span></a><span>等待新消息。（第二个参数以秒为单位超时。）输出</span><span style=' font-family: monospace;'>scandata</span><span>包含接收到的消息数据。</span></div><div class="CodeBlock"><div class="inlineWrapper outputs"><div  class = 'S5'><span style="white-space: pre"><span >scandata = receive(laser,10)</span></span></div><div  class = 'S6'><div class="inlineElement eoOutputWrapper embeddedOutputsVariableStringElement" uid="8636DBA9" data-testid="output_3" style="width: 716px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="textElement eoOutputContent" data-width="686" data-height="222" data-hashorizontaloverflow="false" style="max-height: 261px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><span class="variableNameElement" style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">scandata = </span></div><div style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">  ROS LaserScan message with properties:

       MessageType: 'sensor_msgs/LaserScan'
            Header: [1×1 Header]
          AngleMin: -0.5216
          AngleMax: 0.5243
    AngleIncrement: 0.0016
     TimeIncrement: 0
          ScanTime: 0.0330
          RangeMin: 0.4500
          RangeMax: 10
            Ranges: [640×1 single]
       Intensities: [0×1 single]
  Use showdetails to show the contents of the message</div></div></div></div></div></div><div  class = 'S1'><span>某些消息类型具有与其关联的可视化工具。对于LaserScan消息，</span><a href = "docid:ros_ref.buqbjtl"><span style=' font-family: monospace;'>plot</span></a><span> 打印扫描数据。</span><span style=' font-family: monospace;'>MaximumRange</span><span> name-value对指定最大打印范围。</span></div><div class="CodeBlock"><div class="inlineWrapper"><div  class = 'S9'><span style="white-space: pre"><span >figure</span></span></div></div><div class="inlineWrapper outputs"><div  class = 'S11'><span style="white-space: pre"><span >plot(scandata,</span><span style="color: rgb(170, 4, 249);">'MaximumRange'</span><span >,7)</span></span></div><div  class = 'S6'><div class="inlineElement eoOutputWrapper embeddedOutputsFigure" uid="E2EBF0AF" data-testid="output_4" style="width: 716px;"><div class="figureElement eoOutputContent"><img class="figureImage figureContainingNode" src="" style="width: 560px;"></div></div></div></div></div><h2  class = 'S12'><span>Subscribe Using Callback Functions</span></h2><div  class = 'S1'><span>您可以指定在接收新消息时要调用的函数，而不是使用 </span><a href = "docid:ros_ref.buqbyro"><span style=' font-family: monospace;'>receive</span></a><span> 来获取数据。这允许在订阅者等待新消息时执行其他MATLAB代码。如果要使用多个订阅者，回调是必需的。</span></div><div  class = 'S1'><span>使用回调函数exampleHelperROSPoseCallback订阅</span><span style=' font-family: monospace;'>/pose</span><span> 主题。</span></div><div class="CodeBlock"><div class="inlineWrapper outputs"><div  class = 'S5'><span style="white-space: pre"><span >robotpose = rossubscriber(</span><span style="color: rgb(170, 4, 249);">'/pose'</span><span >,@exampleHelperROSPoseCallback)</span></span></div><div  class = 'S6'><div class="inlineElement eoOutputWrapper embeddedOutputsVariableStringElement" uid="7D6B63A8" data-testid="output_5" style="width: 716px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="textElement eoOutputContent" data-width="686" data-height="122" data-hashorizontaloverflow="false" style="max-height: 261px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><span class="variableNameElement" style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">robotpose = </span></div><div style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">  Subscriber - 属性:

        TopicName: '/pose'
    LatestMessage: [0×1 Twist]
      MessageType: 'geometry_msgs/Twist'
       BufferSize: 1
    NewMessageFcn: @exampleHelperROSPoseCallback</div></div></div></div></div></div><div  class = 'S7'><span>在主工作区和回调函数之间共享数据的一种方法是使用全局变量。定义两个全局变量pos和orient。</span></div><div class="CodeBlock"><div class="inlineWrapper"><div  class = 'S9'><span style="white-space: pre"><span style="color: rgb(14, 0, 255);">global</span><span style="color: rgb(14, 0, 255);"> </span><span >pos</span></span></div></div><div class="inlineWrapper"><div  class = 'S10'><span style="white-space: pre"><span style="color: rgb(14, 0, 255);">global</span><span style="color: rgb(14, 0, 255);"> </span><span >orient</span></span></div></div></div><div  class = 'S7'><span>当接收到有关</span><span style=' font-family: monospace;'>/pose</span><span> 主题的新消息数据时，全局变量pos和orient在exampleHelperROSPoseCallback函数中分配。</span></div><div  class = 'S1'><span>请等待几秒钟，以确保订阅者可以接收消息。最新的位置和方向数据将始终存储在位置和方向变量中。</span></div><div class="CodeBlock"><div class="inlineWrapper"><div  class = 'S9'><span style="white-space: pre"><span >pause(2) </span></span></div></div><div class="inlineWrapper outputs"><div  class = 'S11'><span style="white-space: pre"><span >pos</span></span></div><div  class = 'S6'><div class="inlineElement eoOutputWrapper embeddedOutputsVariableMatrixElement" uid="E307950F" data-testid="output_6" data-width="686" style="width: 716px; white-space: normal; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="matrixElement veSpecifier saveLoad eoOutputContent" style="white-space: normal; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="veVariableName variableNameElement double" style="width: 686px; white-space: normal; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="headerElementClickToInteract" style="white-space: normal; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><span style="white-space: normal; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">pos = </span><span class="veVariableValueSummary veMetaSummary" style="white-space: normal; font-style: normal; color: rgb(179, 179, 179); font-size: 12px;">1×3</span></div></div><div class="valueContainer" data-layout="{&quot;columnWidth&quot;:66,&quot;totalColumns&quot;:&quot;3&quot;,&quot;totalRows&quot;:&quot;1&quot;,&quot;charsPerColumn&quot;:10}" style="white-space: nowrap; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="variableValue" style="width: 200px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">   -0.7863   -0.3794   -0.0709
</div><div class="horizontalEllipsis hide" style="white-space: nowrap; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"></div><div class="verticalEllipsis hide" style="white-space: nowrap; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"></div></div></div></div></div></div><div class="inlineWrapper outputs"><div  class = 'S13'><span style="white-space: pre"><span >orient</span></span></div><div  class = 'S6'><div class="inlineElement eoOutputWrapper embeddedOutputsVariableMatrixElement" uid="953F106D" data-testid="output_7" data-width="686" style="width: 716px; white-space: normal; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="matrixElement veSpecifier saveLoad eoOutputContent" style="white-space: normal; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="veVariableName variableNameElement double" style="width: 686px; white-space: normal; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="headerElementClickToInteract" style="white-space: normal; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><span style="white-space: normal; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">orient = </span><span class="veVariableValueSummary veMetaSummary" style="white-space: normal; font-style: normal; color: rgb(179, 179, 179); font-size: 12px;">1×3</span></div></div><div class="valueContainer" data-layout="{&quot;columnWidth&quot;:66,&quot;totalColumns&quot;:&quot;3&quot;,&quot;totalRows&quot;:&quot;1&quot;,&quot;charsPerColumn&quot;:10}" style="white-space: nowrap; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="variableValue" style="width: 200px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">   -0.3802   -0.7676    0.7587
</div><div class="horizontalEllipsis hide" style="white-space: nowrap; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"></div><div class="verticalEllipsis hide" style="white-space: nowrap; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"></div></div></div></div></div></div></div><div  class = 'S7'><span>如果在命令行中键入</span><span style=' font-family: monospace;'>pos</span><span> and </span><span style=' font-family: monospace;'>orient</span><span>几次，则可以看到值不断更新。</span></div><div  class = 'S1'><span>通过清除subscriber变量停止pose订阅服务器</span></div><div class="CodeBlock"><div class="inlineWrapper"><div  class = 'S8'><span style="white-space: pre"><span >clear </span><span style="color: rgb(170, 4, 249);">robotpose</span></span></div></div></div><div  class = 'S7'><span>注意：除了使用全局函数外，还有其他方法从回调函数中提取信息。例如，可以将handle对象object作为附加参数传递给回调函数。有关定义回调函数的详细信息，请参阅</span><a href = "docid:creating_plots.bt_h1z8"><span>Callback Definition</span></a><span> 文档。</span></div><h2  class = 'S12'><span>Publish Messages</span></h2><div  class = 'S1'><span>创建将ROS字符串消息发送到</span><span style=' font-family: monospace;'>/chatter</span><span>主题的发布者（请参阅</span><a href = "docid:ros_ug.mw_2b4c1056-431d-4413-a812-7cd07f4d9a36"><span>Work with Basic ROS Messages</span></a><span>）。</span></div><div class="CodeBlock"><div class="inlineWrapper outputs"><div  class = 'S5'><span style="white-space: pre"><span >chatterpub = rospublisher(</span><span style="color: rgb(170, 4, 249);">'/chatter'</span><span >, </span><span style="color: rgb(170, 4, 249);">'std_msgs/String'</span><span >)</span></span></div><div  class = 'S6'><div class="inlineElement eoOutputWrapper embeddedOutputsVariableStringElement" uid="90E81BC3" data-testid="output_8" style="width: 716px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="textElement eoOutputContent" data-width="686" data-height="107" data-hashorizontaloverflow="false" style="max-height: 261px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><span class="variableNameElement" style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">chatterpub = </span></div><div style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">  Publisher - 属性:

         TopicName: '/chatter'
    NumSubscribers: 0
        IsLatching: 1
       MessageType: 'std_msgs/String'
</div></div></div></div></div><div class="inlineWrapper"><div  class = 'S14'><span style="white-space: pre"><span >pause(2) </span><span style="color: rgb(2, 128, 9);">% Wait to ensure publisher is registered</span></span></div></div></div><div  class = 'S1'><span>创建并填充要发送到 </span><span style=' font-family: monospace;'>/chatter</span><span> 主题的ROS消息。</span></div><div class="CodeBlock"><div class="inlineWrapper"><div  class = 'S9'><span style="white-space: pre"><span >chattermsg = rosmessage(chatterpub);</span></span></div></div><div class="inlineWrapper outputs"><div  class = 'S11'><span style="white-space: pre"><span >chattermsg.Data = </span><span style="color: rgb(170, 4, 249);">'hello world'</span></span></div><div  class = 'S6'><div class="inlineElement eoOutputWrapper embeddedOutputsVariableStringElement" uid="6C08911B" data-testid="output_9" style="width: 716px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="textElement eoOutputContent" data-width="686" data-height="107" data-hashorizontaloverflow="false" style="max-height: 261px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><span class="variableNameElement" style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">chattermsg = </span></div><div style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">  ROS String message with properties:

    MessageType: 'std_msgs/String'
           Data: 'hello world'

  Use showdetails to show the contents of the message
</div></div></div></div></div></div><div  class = 'S1'><span>使用</span><span style=' font-family: monospace;'>rostopic list</span><span>验证</span><span style=' font-family: monospace;'>/chatter</span><span> 主题在ROS网络中可用。</span></div><div class="CodeBlock"><div class="inlineWrapper outputs"><div  class = 'S5'><span style="white-space: pre"><span >rostopic </span><span style="color: rgb(170, 4, 249);">list</span></span></div><div  class = 'S6'><div class="inlineElement eoOutputWrapper embeddedOutputsTextElement" uid="C72B4BE6" data-testid="output_10" style="width: 716px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="textElement eoOutputContent" data-width="686" data-height="75" data-hashorizontaloverflow="false" style="max-height: 261px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">/chatter
/pose   
/rosout 
/scan   
/tf     </div></div></div></div></div><div  class = 'S1'><span>为</span><span style=' font-family: monospace;'>/chatter</span><span>主题topic定义订阅者。当接收到新消息并在消息中显示字符串内容时，将调用ExampleHellerRoSchatterCallback。</span></div><div class="CodeBlock"><div class="inlineWrapper outputs"><div  class = 'S5'><span style="white-space: pre"><span >chattersub = rossubscriber(</span><span style="color: rgb(170, 4, 249);">'/chatter'</span><span >, @exampleHelperROSChatterCallback)</span></span></div><div  class = 'S6'><div class="inlineElement eoOutputWrapper embeddedOutputsVariableStringElement" uid="428F40E8" data-testid="output_11" style="width: 716px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="textElement eoOutputContent" data-width="686" data-height="122" data-hashorizontaloverflow="false" style="max-height: 261px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><span class="variableNameElement" style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">chattersub = </span></div><div style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">  Subscriber - 属性:

        TopicName: '/chatter'
    LatestMessage: [0×1 String]
      MessageType: 'std_msgs/String'
       BufferSize: 1
    NewMessageFcn: @exampleHelperROSChatterCallback
</div></div></div></div></div></div><div  class = 'S1'><span>将消息发布到 </span><span style=' font-family: monospace;'>/chatter</span><span>主题。该字符串由订阅者回调显示。</span></div><div class="CodeBlock"><div class="inlineWrapper"><div  class = 'S9'><span style="white-space: pre"><span >send(chatterpub,chattermsg)</span></span></div></div><div class="inlineWrapper"><div  class = 'S10'><span style="white-space: pre"><span >pause(2)</span></span></div></div></div><div  class = 'S7'><span>一旦发布字符串消息，就会调用</span><span style=' font-family: monospace;'>exampleHellerRoSchatterCallback</span><span>函数。</span></div><h2  class = 'S12'><span>Shut Down ROS Network</span></h2><div  class = 'S1'><span>从ROS网络中删除示例节点、发布者和订阅者。清除全局变量</span><span style=' font-family: monospace;'>pos</span><span> and </span><span style=' font-family: monospace;'>orient</span><span>。</span></div><div class="CodeBlock"><div class="inlineWrapper"><div  class = 'S9'><span style="white-space: pre"><span >exampleHelperROSShutDownSampleNetwork</span></span></div></div><div class="inlineWrapper"><div  class = 'S10'><span style="white-space: pre"><span >clear </span><span style="color: rgb(170, 4, 249);">global </span><span style="color: rgb(170, 4, 249);">pos</span><span style="color: rgb(170, 4, 249);"> </span><span style="color: rgb(170, 4, 249);">orient</span></span></div></div></div><div  class = 'S7'><span>关闭ROS master并删除全局节点global node。</span></div><div class="CodeBlock"><div class="inlineWrapper outputs"><div  class = 'S5'><span style="white-space: pre"><span >rosshutdown</span></span></div><div  class = 'S6'><div class="inlineElement eoOutputWrapper embeddedOutputsTextElement" uid="849D402B" data-testid="output_12" style="width: 716px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="textElement eoOutputContent" data-width="686" data-height="32" data-hashorizontaloverflow="false" style="max-height: 261px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">Shutting down global node /matlab_global_node_36339 with NodeURI http://LAPTOP-TG3AQJDL:14641/
Shutting down ROS master on http://192.168.118.1:11311.</div></div></div></div></div><h2  class = 'S12'><span>Next Steps</span></h2><ul  class = 'S2'><li  class = 'S3'><span>要了解更多有关如何在MATLAB中处理ROS消息的信息，请参阅使用基本ROS消息和使用专用ROS消息</span><span> </span><a href = "docid:ros_ug.mw_2b4c1056-431d-4413-a812-7cd07f4d9a36"><span>Work with Basic ROS Messages</span></a><span> and</span><span> </span><a href = "docid:ros_ug.mw_f993bbbe-25de-434f-bfd0-e5243256b23c"><span>Work with Specialized ROS Messages</span></a><span>.</span></li><li  class = 'S3'><span>要了解ROS服务，请参阅 </span><a href = "docid:ros_ug.mw_70dbf089-5821-4e67-b96f-f659aea10c0c"><span>Call and Provide ROS Services</span></a><span>.</span></li></ul><div  class = 'S1'><span></span></div><div  class = 'S1'><span style=' font-style: italic;'>Copyright 2014-2016 The MathWorks, Inc.</span></div>
<br>
<!-- 
##### SOURCE BEGIN #####
%% Exchange Data with ROS Publishers and Subscribers
% ROS节点交换数据的主要机制是发送和接收消息_messages_。消息在一个主题_topic_上传输，每个主题在ROS网络中都有一个唯一的名称。如果节点想要共享信息，它将使用发布者_publisher_向主题发送数据。要接收该信息的节点使用同一主题的订阅者_subscriber_。除了其唯一的名称之外，每个主题还具有一个消息类型_message 
% type_，该类型决定了能够在该主题下传输的消息的类型。
% 
% 此发布者和订阅者通信具有以下特征： 
%% 
% * 主题用于多对多通信。多个发布者可以向同一主题发送消息，多个订阅者可以接收这些消息。Topics are used for many-to-many 
% communication. Many publishers can send messages to the same topic and many 
% subscribers can receive them.
% * 发布者和订阅者通过主题分离，可以按任何顺序创建和销毁。即使没有活动订阅服务器，也可以将消息发布到主题。
%% 
% 主题、发布者和订阅者的概念如图所示：
% 
% 
% 
% 这个例子展示了如何在ROS网络中发布和订阅主题。它还展示了如何：
%% 
% * 等待收到新消息
% * 使用回调callbacks在后台处理新消息messages。
%% 
% 首要条件: <docid:ros_ug.mw_cb3fdf75-613d-45b1-90e1-aad102b9a24a Get Started with 
% ROS>,  <docid:ros_ug.mw_d625a603-7f37-4925-9470-2de734937434 Connect to a ROS 
% Network>
%% Subscribe and Wait for Messages
% 使用 <docid:ros_ref.bupf5_j_1 |rosinit|> 命令在MATLAB®中启动ROS主机。

rosinit
%% 
% 使用提供的helper函数exampleHelperROSCreateSampleNetwork创建一个包含多个发布者和订阅者的示例ROS网络。

exampleHelperROSCreateSampleNetwork
%% 
% 使用<docid:ros_ref.bupf5_j_14 |rostopic|>列表查看哪些主题可用。

rostopic list
%% 
% 使用|rostopic info|检查是否有任何节点正在发布到 |/scan|主题。下面的命令显示|node_3|正在向其发布。

rostopic info /scan
%% 
% 使用<docid:ros_ref.bupf5_j_9 |rossubscriber|> 订阅 |/scan|主题。如果主题已经存在于ROS网络中（如这里的情况），|rossubscriber|会自动检测其消息类型，因此您不需要指定它。

laser = rossubscriber('/scan');
pause(2)
%% 
% 使用<docid:ros_ref.buqbyro |receive|>等待新消息。（第二个参数以秒为单位超时。）输出|scandata|包含接收到的消息数据。

scandata = receive(laser,10)
%% 
% 某些消息类型具有与其关联的可视化工具。对于LaserScan消息，<docid:ros_ref.buqbjtl |plot|> 打印扫描数据。|MaximumRange| 
% name-value对指定最大打印范围。

figure
plot(scandata,'MaximumRange',7)
%% Subscribe Using Callback Functions
% 您可以指定在接收新消息时要调用的函数，而不是使用 <docid:ros_ref.buqbyro |receive|> 来获取数据。这允许在订阅者等待新消息时执行其他MATLAB代码。如果要使用多个订阅者，回调是必需的。
% 
% 使用回调函数exampleHelperROSPoseCallback订阅|/pose| 主题。

robotpose = rossubscriber('/pose',@exampleHelperROSPoseCallback)
%% 
% 在主工作区和回调函数之间共享数据的一种方法是使用全局变量。定义两个全局变量pos和orient。

global pos
global orient
%% 
% 当接收到有关|/pose| 主题的新消息数据时，全局变量pos和orient在exampleHelperROSPoseCallback函数中分配。
% 
% 请等待几秒钟，以确保订阅者可以接收消息。最新的位置和方向数据将始终存储在位置和方向变量中。

pause(2) 
pos
orient
%% 
% 如果在命令行中键入|pos| and |orient|几次，则可以看到值不断更新。
%% 
% 通过清除subscriber变量停止pose订阅服务器

clear robotpose
%% 
% 注意：除了使用全局函数外，还有其他方法从回调函数中提取信息。例如，可以将handle对象object作为附加参数传递给回调函数。有关定义回调函数的详细信息，请参阅<docid:creating_plots.bt_h1z8 
% Callback Definition> 文档。
%% Publish Messages
% 创建将ROS字符串消息发送到|/chatter|主题的发布者（请参阅<docid:ros_ug.mw_2b4c1056-431d-4413-a812-7cd07f4d9a36 
% Work with Basic ROS Messages>）。

chatterpub = rospublisher('/chatter', 'std_msgs/String')
pause(2) % Wait to ensure publisher is registered
%% 
% 创建并填充要发送到 |/chatter| 主题的ROS消息。

chattermsg = rosmessage(chatterpub);
chattermsg.Data = 'hello world'
%% 
% 使用|rostopic list|验证|/chatter| 主题在ROS网络中可用。

rostopic list
%% 
% 为|/chatter|主题topic定义订阅者。当接收到新消息并在消息中显示字符串内容时，将调用ExampleHellerRoSchatterCallback。

chattersub = rossubscriber('/chatter', @exampleHelperROSChatterCallback)
%% 
% 将消息发布到 |/chatter|主题。该字符串由订阅者回调显示。

send(chatterpub,chattermsg)
pause(2)
%% 
% 一旦发布字符串消息，就会调用|exampleHellerRoSchatterCallback|函数。
%% Shut Down ROS Network
% 从ROS网络中删除示例节点、发布者和订阅者。清除全局变量|pos| and |orient|。

exampleHelperROSShutDownSampleNetwork
clear global pos orient
%% 
% 关闭ROS master并删除全局节点global node。

rosshutdown
%% Next Steps
%% 
% * 要了解更多有关如何在MATLAB中处理ROS消息的信息，请参阅使用基本ROS消息和使用专用ROS消息 <docid:ros_ug.mw_2b4c1056-431d-4413-a812-7cd07f4d9a36 
% Work with Basic ROS Messages> and <docid:ros_ug.mw_f993bbbe-25de-434f-bfd0-e5243256b23c 
% Work with Specialized ROS Messages>.
% * 要了解ROS服务，请参阅 <docid:ros_ug.mw_70dbf089-5821-4e67-b96f-f659aea10c0c Call 
% and Provide ROS Services>.
%% 
% 
% 
% _Copyright 2014-2016 The MathWorks, Inc._
##### SOURCE END #####
-->
</div></body></html>